package com.tfjybj.itoo.teach.provider.service.impl;

import org.apache.dubbo.config.annotation.Reference;;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dmsdbj.itoo.authorizationManagement.entity.AllusersEntity;
import com.dmsdbj.itoo.authorizationManagement.entity.OrganizationUserEntity;
import com.dmsdbj.itoo.authorizationManagement.facade.AllusersFacade;
import com.dmsdbj.itoo.authorizationManagement.facade.OrganizationUserFacade;
import com.dmsdbj.itoo.authorizationManagement.facade.RoleFacade;
import com.dmsdbj.itoo.authorizationManagement.facade.UserRoleFacade;
import com.dmsdbj.itoo.tool.base.service.impl.BaseServicePlusImpl;
import com.dmsdbj.itoo.tool.business.ItooResult;
import com.dmsdbj.itoo.tool.uuid.BaseUuidUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tfjybj.itoo.teach.entity.StaffEntity;
import com.tfjybj.itoo.teach.entity.StaffInstitutionEntity;
import com.tfjybj.itoo.teach.model.AcademyModel;
import com.tfjybj.itoo.teach.model.StaffModel;
import com.tfjybj.itoo.teach.provider.dao.CourseDao;
import com.tfjybj.itoo.teach.provider.dao.StaffDao;
import com.tfjybj.itoo.teach.provider.service.AcademyService;
import com.tfjybj.itoo.teach.provider.service.StaffInstitutionService;
import com.tfjybj.itoo.teach.provider.service.StaffService;
import com.tfjybj.itoo.teach.template.StaffTemplate;
import lombok.extern.slf4j.Slf4j;
import org.jplus.hyberbin.excel.utils.ExcelUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.*;

import static com.tfjybj.itoo.teach.provider.until.DemoConstants.*;

/**
 * StaffService接口实现类
 * ${base}表
 *
 * @author 田成荣
 * @version 2.0.0
 * @since 2.0.0 2018-11-08 19:34:10
 */
@Service("staffService")
@Slf4j
public class StaffServiceImpl extends BaseServicePlusImpl<StaffDao, StaffEntity> implements StaffService {

    //region 模板生成
    @Resource
    private transient StaffDao staffDao;
    @Resource
    private transient CourseDao courseDao;
    @Resource
    private AcademyService academyService;
    @Resource
    private StaffInstitutionService staffInstitutionService;
    @Resource
    private transient RedisTemplate<String, StaffTemplate> redisTemplate;


    @Override
    public PageInfo<StaffModel> queryByLikeName(String name, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        name = name.trim();
        List<StaffModel> staffInfo = staffDao.queryLikeName(name);
        staffInfo = this.changeValue(staffInfo);
        return new PageInfo<>(staffInfo);
    }
    //endregion

    /* **********************************以下为非模板生成的内容********************************* */
    @Resource
    private StaffService staffService;
//    @Resource
//    private AllusersFacade allusersFacade;
//    @Resource
//    private RoleFacade roleFacade;
//    @Resource
//    private UserRoleFacade userRoleFacade;
//    @Resource
//    private OrganizationUserFacade organizationUserFacade;
    /**
     * 根据教师编号查询staff
     *
     * @param code 教师编码
     * @return staffModel
     * @author 张家豪
     * @since 2018.11.15 20:11
     */
    @Override
    public List<StaffModel> queryByCode(String code) {
        return staffDao.queryByCode(code);
    }

    /**
     * 根据学院ID查询本学院教师
     *
     * @param academy 学院ID
     * @return staffModel
     * @author 张家豪
     * @since 2018.11.18 14:09
     */
    @Override
    public List<StaffModel> queryStaffByAcademy(String academy) {
        return staffDao.queryStaffByAcademy(academy);
    }

    /**
     * 查询所有教师信息（初始化页面）
     *
     * @return staffModel
     * @author 张家豪
     * @since 2018.11.22 17:07
     */
    @Override
    public PageInfo<StaffModel> queryAllStaff(Integer pageNo, Integer pageSize) {
        PageHelper.startPage(pageNo, pageSize);
        List<StaffModel> staffInfo = staffDao.queryAllStaff();
        if (staffInfo.size() > 0) {
            //获取学院名称
            staffInfo = this.changeValue(staffInfo);
        }
        return new PageInfo<>(staffInfo);
    }

    /**
     * 转换字段内容
     *
     * @param staffInfo 总集合
     * @return staffModel 转换完成的数据
     * @author 张家豪
     * @since 2018年11月22日17:32:41
     */
    private List<StaffModel> changeValue(List<StaffModel> staffInfo) {
        //2、查询学院名称
        //2、1列出所需ID
        List<String> academyIds = new ArrayList<>();
        for (int i = 0; i < staffInfo.size(); i++) {
            academyIds.add(staffInfo.get(i).getInstitutionId());
        }
        //2、2HashSet去重
        HashSet<String> h = new HashSet<>(academyIds);
        academyIds.clear();
        academyIds.addAll(h);
        if (academyIds.size() > 0) {
            //2、3调接口查询学院名称
            List<AcademyModel> academyList = academyService.queryInfoByAcadIdOrInstId(academyIds);
            //2、4 List转Map
            Map<String, String> academyMap = new HashMap<>();
            for (int i = 0; i < academyList.size(); i++) {
                academyMap.put(academyList.get(i).getId(), academyList.get(i).getName());
            }
            //1、4填充数据
            for (int i = 0; i < staffInfo.size(); i++) {
                String academyId = staffInfo.get(i).getInstitutionId();
                staffInfo.get(i).setInstitutionName(academyMap.get(academyId));
            }
        }
        return staffInfo;
    }

    /**
     * 根据教职工号或者机构Id查询staff
     *
     * @param code    教职工号
     * @param academy 机构名称
     * @return staffModel
     * @author 张家豪
     * @since 2018.11.22 20:23
     */
    @Override
    public PageInfo<StaffModel> queryStaffByCodeAndAcademy(Integer pageNo, Integer pageSize, String code, String academy) {
        PageHelper.startPage(pageNo, pageSize);
        code = code.trim();
        academy = academy.trim();
        List<StaffModel> staffInfo = staffDao.queryStaffByCodeAndAcademy(code, academy);
        if (staffInfo.size() > 0) {
            //获取学院名称
            staffInfo = this.changeValue(staffInfo);
        }
        return new PageInfo<>(staffInfo);
    }


    @Override
    public ItooResult exportStaffInfo(HttpServletResponse response, String staffName, String staffCode, String academy) {
        staffName = staffName.trim();
        staffCode = staffCode.trim();
        academy = academy.trim();
        // 需要导出的数据
        List<StaffModel> staffInfo;
        if (!StringUtils.isEmpty(staffName)) {
            staffInfo = staffDao.queryLikeName(staffName);
        } else {
            staffInfo = staffDao.queryStaffByCodeAndAcademy(staffCode, academy);
        }
        staffInfo = this.changeValue(staffInfo);

        // 定义excel字段
        Map<Serializable, Serializable> map = new HashMap<>();
        map.put(SHEET_NAME, "教师信息");
        //要导出的字段
        map.put(COLUMNS, new String[]{"code", "name", "sex", "identityCardId", "institutionName", "jobtitleId", "dutyId"});
        //导出表格的标题
        map.put(TITLE, "教师信息");
        map.put(NAME, "教师信息表");

        //数据导入到模板
        List<StaffTemplate> staffTemplates = new ArrayList<>();
        for (StaffModel staffModel : staffInfo) {
            StaffTemplate staffTemplate = new StaffTemplate();
            BeanUtils.copyProperties(staffModel, staffTemplate);
            staffTemplates.add(staffTemplate);
        }

        //不为空进行导出
        if (staffTemplates.size() == 0) {
            return ItooResult.build(ItooResult.FAIL, "没有要导出的数据");
        }
        map.put(DATA_LIST, (Serializable) staffTemplates);
        //导出
        try {
            ExcelUtil.exportExcel(map, response);
        } catch (Exception e) {
            log.error("导出失败,未知的异常--" + e);
            return ItooResult.build(ItooResult.FAIL, "导出信息失败！");
        }
        return ItooResult.build(ItooResult.SUCCESS, "导出信息成功！");
    }

    /**
     * 根据多个机构查询staff
     *
     * @param academys 机构id集合
     * @return staffModel
     * @author 张家豪
     * @since 2018.11.24 20:43
     */
    @Override
    public PageInfo<StaffModel> queryByAcademys(List<String> academys, Integer pageNo, Integer pageSize) {
        PageHelper.startPage(pageNo, pageSize);
        List<StaffModel> staffInfo = staffDao.queryByAcademys(academys);
        return new PageInfo<>(staffInfo);
    }

    /**
     * 导入教师信息
     *
     * @param multipartFile 批量导入的文件
     * @param request       请求
     * @param response      响应
     * @return itooResult 批量导入的结果
     * @author 张家豪
     * @since 2018.11.25 08:38
     */
    @Override
    public ItooResult importStaff(MultipartFile multipartFile, HttpServletRequest request, HttpServletResponse response) {
        response.setContentType("UTF-8");
        try {
            String fileName = multipartFile.getOriginalFilename();
            if (fileName == null) {
                log.error("导入失败，fileName is null");
                return ItooResult.build(ItooResult.FAIL, "传入的文件为空");
            }
            // excel解析成list
            Map<Serializable, Serializable> map = new HashMap<>(4);
            map.put(SHEET_NAME, "教师信息");
            map.put(CLASS, StaffTemplate.class);
            List<StaffTemplate> staffImportList = ExcelUtil.importExcel(Objects.requireNonNull(fileName), map, request, response);
            if (StringUtils.isEmpty(staffImportList)) {
                return ItooResult.build(ItooResult.FAIL, "导入的数据为空");
            }
            // 定义导入错误数据集合
            List<StaffTemplate> errorStaffList = new ArrayList<>();
            String errorListId = BaseUuidUtils.base58Uuid();
            Long size = redisTemplate.opsForZSet().size(errorListId);
            size = size == null ? 0L : size;
            // 循环处理数据
            for (StaffTemplate excelStaff : staffImportList) {
                // 数据验证
                if (!this.verify(excelStaff)) {
                    StaffTemplate staffTemplate = new StaffTemplate();
                    BeanUtils.copyProperties(excelStaff, staffTemplate);
                    errorStaffList.add(staffTemplate);
                    redisTemplate.opsForZSet().add(errorListId, staffTemplate, size + 1);
                    continue;
                }
                // 获取学院id
                String academyId = this.getAcademyId(excelStaff.getInstitutionName());
                excelStaff.setInstitutionId(academyId);
                StaffEntity staffEntity = new StaffEntity();
                BeanUtils.copyProperties(excelStaff, staffEntity);
                // 添加教师信息
                this.save(staffEntity);
                this.addToAuth(staffEntity,academyId);
                // 根据code查询staffId-添加时用
                String staffId = staffDao.queryByCode(staffEntity.getCode()).get(0).getId();
                // 添加教师-机构对应信息
                StaffInstitutionEntity staffInstitutionEntity = new StaffInstitutionEntity();
                if (academyId == null) {
                    academyId = "";
                }
                staffInstitutionEntity.setStaffId(staffId);
                staffInstitutionEntity.setInstitutionId(academyId);
                staffInstitutionEntity.setIsMain(1);

                staffInstitutionService.save(staffInstitutionEntity);
            }
            // 不符合条件的信息返回
            if (errorStaffList.size() > 0) {
                return ItooResult.build("0001", "部分教师信息导入失败", errorListId);
            }
        } catch (Exception e) {
            return ItooResult.build(ItooResult.FAIL, "教师信息导入异常");
        }
        return ItooResult.build(ItooResult.SUCCESS, "教师信息导入成功");
    }

    /**
     * 批量导入前验证数据是否符合要求
     *
     * @param staffTemplate 需要验证的数据
     * @return 数据验证通过或不通过
     * @author 张家豪
     * @since 2018.11.25 08:59
     */
    private boolean verify(StaffTemplate staffTemplate) {
        // 判断非空字段是否有值
        if (StringUtils.isEmpty(staffTemplate.getCode())) {
            staffTemplate.setFailReason("教职工号未填写");
            log.warn("导入失败，code未填写，导入信息-", staffTemplate);
            return false;
        }
        if (StringUtils.isEmpty(staffTemplate.getName())) {
            staffTemplate.setFailReason("教师姓名未填写");
            log.warn("导入失败，name未填写，导入信息-", staffTemplate);
            return false;
        }
        if (StringUtils.isEmpty(staffTemplate.getInstitutionName())) {
            staffTemplate.setFailReason("学院未填写");
            log.warn("导入失败，InstitutionName未填写，导入信息-", staffTemplate);
            return false;
        }
        // 判断教师编码是否重复
        if (staffDao.queryByCode(staffTemplate.getCode()).size() > 0) {
            staffTemplate.setFailReason("教职工号已存在");
            log.warn("导入失败，code已存在，导入信息-", staffTemplate);
            return false;
        }
        return true;
    }

    /**
     * 根据学院名称获取学院ID-导入用
     *
     * @param academyName 学院id
     * @return 学院id
     * @author 张家豪
     * @since 2018.11.25 09:27
     */
    private String getAcademyId(String academyName) {
        return courseDao.getAcademyIdByName(academyName);
    }

    /**
     * 下载模板-导入用
     *
     * @param response 响应
     * @return 下载成功或失败
     * @author 张家豪
     * @since 2018.11.21 09:39
     */
    @Override
    public Boolean downTemplate(HttpServletResponse response) {
        Map<Serializable, Serializable> map = new HashMap<>(16);
        List<StaffTemplate> templateList = new ArrayList<>();
        StaffTemplate staffExportTemplate = new StaffTemplate();
        staffExportTemplate.setCode("12058");
        staffExportTemplate.setName("张三");
        staffExportTemplate.setIdentityCardId("131121155802512354");
        staffExportTemplate.setSex("男");
        staffExportTemplate.setJobtitleId("不知道什么职称");
        staffExportTemplate.setDutyId("不知道什么职务");
        staffExportTemplate.setInstitutionName("体育学院");
        templateList.add(staffExportTemplate);
        //excel设置
        map.put(SHEET_NAME, "教师信息");
        map.put(COLUMNS, new String[]{"code", "name", "identityCardId", "sex", "jobtitleId", "dutyId", "institutionName"});
        map.put(TITLE, "教师信息模板");
        map.put(NAME, "教师信息模板");
        map.put(DATA_LIST, (Serializable) templateList);

        try {
            ExcelUtil.exportExcel(map, response);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 查询所有教师信息-接口
     *
     * @return staffEntity
     * @author 张家豪
     * @since 2018.11.27 15:56
     */
    @Override
    public List<StaffEntity> queryAllStaffInfo(String institutionId) {
        return staffDao.queryAllStaffInfo(institutionId);
    }

    @Override
    public boolean downErrorList(String errorListId, HttpServletResponse response) {
        // redis 取出没有成功导入的人员信息
        Set set = redisTemplate.opsForZSet().range(errorListId, 0, -1);
        List<StaffTemplate> staffTemplates = new ArrayList<>(set);
        // 清空redis数据
        redisTemplate.delete(errorListId);

        //导出
        if (staffTemplates.size() == 0) {
            return false;
        }
        Map<Serializable, Serializable> errorMap = new HashMap<>(16);
        errorMap.put(NAME, "未导入的信息");
        errorMap.put(SHEET_NAME, "课程信息");
        errorMap.put(TITLE, "未导入的信息");
        errorMap.put(COLUMNS, new String[]{"code", "name", "identityCardId", "sex", "jobtitleId", "dutyId", "institutionName","failReason"});
        errorMap.put(DATA_LIST, (Serializable) staffTemplates);
        try {
            ExcelUtil.exportExcel(errorMap, response);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    @Override
    public boolean addToAuth(StaffEntity staff, String institutionId) {
        try {
//            //获得教师id
//            QueryWrapper<StaffEntity> staffEntityQueryWrapper = new QueryWrapper<>();
//            staffEntityQueryWrapper.eq("code", staff.getCode());
//            List<StaffEntity> stafflist = staffService.list(staffEntityQueryWrapper);
//            String staffId = stafflist.get(0).getId();
//
//            // 调用权限接口，添加学生角色
//            AllusersEntity allusersEntity = new AllusersEntity();
//            allusersEntity.setId(staffId);
//            allusersEntity.setUserCode(staff.getCode());
//            allusersEntity.setUserName(staff.getName());
//            allusersEntity.setIsLock(0);
//            allusersEntity.setEmail(staff.getEmail());
//            allusersEntity.setTelNum(staff.getTelNum());
//            allusersEntity.setPassword(staff.getCode());
//            allusersEntity.setSchoolNo("111222");
//            List<AllusersEntity> allusersEntityList = new ArrayList<>();
//            allusersEntityList.add(allusersEntity);
//            allusersFacade.insertUserList(allusersEntityList);
//
//            //插入角色关系表
//            String roleId = roleFacade.queryRoleId("教师", "lfsfxy111222");
//            List<String> userIds = new ArrayList<>();
//            userIds.add(staffId);
//            userRoleFacade.insertUserRole(userIds, roleId);
//
//            //插入组织机构表
//            List<OrganizationUserEntity> organizationUserEntityList = new ArrayList<>();
//            OrganizationUserEntity organizationUserEntity = new OrganizationUserEntity();
//            organizationUserEntity.setOrganizationId(institutionId);
//            organizationUserEntity.setUserId(staffId);
//            organizationUserEntity.setCompanyId("lfsfxy111222");
//            organizationUserEntityList.add(organizationUserEntity);
//            organizationUserFacade.insertFromBasic(organizationUserEntityList);
        }
        catch (Exception e) {
            return false;
        }
        return true;
    }

}
